<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { CaseDetailDTO, ComponentDTO, FileInfoVo, getCompleteCaseDetail, KnowledgeDTO } from '@/api/kg/case';
import { createComponent, getComponentFiles, getComponentKnowledge, updateComponent, updateComponentFiles, updateComponentKnowledge } from '@/api/kg/component';
import { ElMessage } from 'element-plus';
import { getCaseDifficulty, getCaseStatus } from '@/views/kg/case/utils/columns';
import { ArrowLeft, ArrowRight, Calendar, Collection, Document, Download, Edit, Folder, Plus, Search, User, View } from '@element-plus/icons-vue';
import { MdEditor, MdPreview } from 'md-editor-v3';
import 'md-editor-v3/lib/preview.css';
import 'md-editor-v3/lib/style.css';
import FilePreview from '@/components/FilePreview/FilePreview.vue';
import { fetchUploadFile } from '@/api/system/system';
import { downloadFilesByFileId, fetchGetAllFilesList } from '@/api/files';
import { useKnowledgeStore } from '@/store/kg/knowledge';
import AssignKnowledgeToComponent from './components/AssignKnowledgeToComponent.vue';
import { useUserStore } from '@/store/system/user';
import { hasPerms } from '@/utils/auth';

const route = useRoute();
const router = useRouter();
const loading = ref(false);
const caseDetail = ref<CaseDetailDTO | null>(null);
const activeComponent = ref<string | null>(null);
const userStore = useUserStore();

// 组件编辑相关
const editDialogVisible = ref(false);
const editComponentForm = ref<ComponentDTO>({
	nodeId: '',
	name: '',
	description: '',
	content: '',
});
const editFormLoading = ref(false);
const activeTab = ref('basic');

// 创建组件相关
const createDialogVisible = ref(false);
const createComponentForm = ref<ComponentDTO>({
	name: '',
	description: '',
	content: '',
});
const createFormLoading = ref(false);
const isCreating = ref(false);

// 文件管理相关
const componentFiles = ref<FileInfoVo[]>([]);
const fileLoading = ref(false);
// 文件搜索
const fileSearchKeyword = ref('');
const allSystemFiles = ref<any[]>([]);
const filteredSystemFiles = computed(() => {
	if (!fileSearchKeyword.value) return allSystemFiles.value;
	const keyword = fileSearchKeyword.value.toLowerCase();
	return allSystemFiles.value.filter(file => file.filename.toLowerCase().includes(keyword) || formatFileType(file.fileType).toLowerCase().includes(keyword));
});

// 监听筛选结果变化，重新设置选中状态
watch(filteredSystemFiles, () => {
	// 当筛选结果变化时，延迟一下再更新选中状态
	setTimeout(() => {
		setTableSelection();
	}, 100);
});

// 文件表格引用
const fileTableRef = ref();

// 选中的文件ID
const selectedFileIds = ref<string[]>([]);

// 初始化选中的文件
const initSelectedFiles = () => {
	// 获取组件已关联的文件ID，使用fileId字段
	selectedFileIds.value = componentFiles.value.map(item => item.fileId || '');
};

// 处理表格选择变化
const handleSelectionChange = selection => {
	// 从选中的文件中提取id，并过滤掉空值
	selectedFileIds.value = selection.map(item => item.id).filter(Boolean);
	console.log('已选择文件IDs:', selectedFileIds.value);
};

// 设置表格默认选中行
const setTableSelection = () => {
	if (!fileTableRef.value) return;

	// 清空现有选择
	fileTableRef.value.clearSelection();

	// 设置选中行，使用fileId和id进行匹配
	for (const row of allSystemFiles.value) {
		if (componentFiles.value.some(file => file.fileId === row.id)) {
			fileTableRef.value.toggleRowSelection(row, true);
		}
	}
};

// 知识点管理相关
const componentKnowledge = ref<KnowledgeDTO[]>([]);
const knowledgeLoading = ref(false);
const selectedKnowledgeIds = ref<string[]>([]);
const allKnowledgeOptions = ref<any[]>([]);
const knowledgeAssignRef = ref();

// 初始化知识点store
const knowledgeStore = useKnowledgeStore();

// 文件类型映射
const formatFileType = (type: string | undefined): string => {
	if (!type) return '未知类型';

	// 文件类型映射
	const typeMap: Record<string, string> = {
		'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word文档 (DOCX)',
		'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel表格 (XLSX)',
		'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint (PPTX)',
		'application/pdf': 'PDF文档',
		'application/msword': 'Word文档 (DOC)',
		'application/vnd.ms-excel': 'Excel表格 (XLS)',
		'application/vnd.ms-powerpoint': 'PowerPoint (PPT)',
		'text/plain': '文本文件',
		'image/jpeg': 'JPEG图片',
		'image/png': 'PNG图片',
		'image/gif': 'GIF图片',
		'text/html': 'HTML文件',
		'application/json': 'JSON文件',
		'application/xml': 'XML文件',
	};

	return typeMap[type] || type;
};

// 获取案例详情
const fetchCaseDetail = async (id: string) => {
	loading.value = true;
	try {
		console.log('获取案例详情，ID:', id);
		const res = await getCompleteCaseDetail(id);
		console.log('案例详情响应:', res);
		if (res && res.data) {
			caseDetail.value = res.data;
			// 如果有组件，默认选中第一个
			if (res.data.components && res.data.components.length > 0) {
				activeComponent.value = res.data.components[0].nodeId;
			}
		} else {
			ElMessage.error('获取案例详情失败');
		}
	} catch (error) {
		console.error('获取案例详情失败:', error);
		ElMessage.error('获取案例详情失败');
	} finally {
		loading.value = false;
	}
};

// 获取当前组件的文件
const getCurrentComponentFiles = (componentId: string): FileInfoVo[] => {
	if (!caseDetail.value || !caseDetail.value.componentFiles) return [];
	return caseDetail.value.componentFiles[componentId] || [];
};

// 获取当前组件的知识点
const getCurrentComponentKnowledge = (componentId: string): KnowledgeDTO[] => {
	if (!caseDetail.value || !caseDetail.value.componentKnowledge) return [];
	return caseDetail.value.componentKnowledge[componentId] || [];
};

// 根据知识点难度获取颜色类型
const getKnowledgeTagType = (level: number) => {
	switch (level) {
		case 1:
			return 'success';
		case 2:
			return 'warning';
		case 3:
			return 'danger';
		default:
			return 'info';
	}
};

// 格式化时间
const formatDate = (dateStr: string) => {
	if (!dateStr) return '';
	const date = new Date(dateStr);
	return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
};

// 打开文件（下载）
const openFile = (url: string) => {
	if (!url) return;
	window.open(url, '_blank');
};

// 预览文件
const previewFile = (url: string) => {
	if (!url) return;
	const previewServer = 'http://127.0.0.1:8012';

	// Base64编码
	const base64Encode = (str: string): string => {
		if (window && window.btoa) {
			return window.btoa(unescape(encodeURIComponent(str)));
		}
		return str;
	};

	// 拼接预览URL并打开
	const previewUrl = `${previewServer}/onlinePreview?url=${encodeURIComponent(base64Encode(url))}`;
	window.open(previewUrl, '_blank');
};

// 返回列表页
const goBack = () => {
	// 返回案例列表页
	router.push('/kg/case');
};

// 打开创建组件对话框
const openCreateDialog = () => {
	// 重置表单
	createComponentForm.value = {
		name: '',
		description: '',
		content: '',
	};

	// 重置标签页
	activeTab.value = 'basic';
	isCreating.value = true;

	// 打开对话框
	createDialogVisible.value = true;
};

// 创建组件
const handleCreateComponent = async () => {
	if (!createComponentForm.value.name || !createComponentForm.value.description) {
		ElMessage.error('组件名称和描述不能为空');
		return;
	}

	createFormLoading.value = true;
	try {
		// 调用API创建组件
		const res = await createComponent(route.params.id as string, createComponentForm.value);

		if (res.code === 200) {
			ElMessage.success('组件创建成功');
			// 获取创建后的组件ID
			const componentId = res.data.nodeId;
			// 重新获取案例详情
			await fetchCaseDetail(route.params.id as string);
			// 关闭对话框
			createDialogVisible.value = false;
			// 选中新创建的组件
			if (componentId) {
				activeComponent.value = componentId;
			}
		} else {
			ElMessage.error(res.message || '组件创建失败');
		}
	} catch (error) {
		console.error('创建组件失败:', error);
		ElMessage.error('创建组件失败');
	} finally {
		createFormLoading.value = false;
	}
};

// 打开编辑组件对话框
const openEditDialog = async (component: ComponentDTO) => {
	editComponentForm.value = {
		nodeId: component.nodeId,
		name: component.name,
		description: component.description,
		content: component.content,
	};

	// 重置标签页
	activeTab.value = 'basic';

	// 打开对话框
	editDialogVisible.value = true;

	// 加载组件关联的文件
	await loadComponentFiles(component.nodeId);

	// 加载组件关联的知识点
	await loadComponentKnowledge(component.nodeId);
};

// 加载组件关联的文件
const loadComponentFiles = async (componentId: string) => {
	if (!componentId) return;

	fileLoading.value = true;
	try {
		const res = await getComponentFiles(componentId);
		if (res.data) {
			componentFiles.value = res.data;
			console.log('已关联的文件:', componentFiles.value);

			// 加载所有系统文件用于选择
			await loadAllSystemFiles();

			// 设置表格选中状态
			setTimeout(() => {
				setTableSelection();
			}, 100);
		}
	} catch (error) {
		console.error('获取组件文件失败:', error);
		ElMessage.error('获取组件文件失败');
	} finally {
		fileLoading.value = false;
	}
};

// 加载组件关联的知识点
const loadComponentKnowledge = async (componentId: string) => {
	if (!componentId) return;

	knowledgeLoading.value = true;
	try {
		const res = await getComponentKnowledge(componentId);
		if (res.data) {
			componentKnowledge.value = res.data;
			selectedKnowledgeIds.value = res.data.map(item => item.nodeId);
		}
	} catch (error) {
		console.error('获取组件知识点失败:', error);
		ElMessage.error('获取组件知识点失败');
	} finally {
		knowledgeLoading.value = false;
	}
};

// 保存组件编辑
const saveComponentEdit = async () => {
	if (!editComponentForm.value.nodeId) {
		ElMessage.error('组件ID不存在');
		return;
	}

	if (!editComponentForm.value.name || !editComponentForm.value.description) {
		ElMessage.error('组件名称和描述不能为空');
		return;
	}

	editFormLoading.value = true;
	try {
		// 调用API更新组件
		const res = await updateComponent(editComponentForm.value.nodeId, editComponentForm.value);

		if (res.code === 200) {
			ElMessage.success('组件更新成功');
			// 刷新组件数据
			fetchCaseDetail(route.params.id as string);
			editDialogVisible.value = false;
		} else {
			ElMessage.error(res.message || '组件更新失败');
		}
	} catch (error) {
		console.error('更新组件失败:', error);
		ElMessage.error('更新组件失败');
	} finally {
		editFormLoading.value = false;
	}
};

// 上传图片到Markdown编辑器
const onUploadImg = async (files: any, callback: any) => {
	const res = await Promise.all(
		files.map((file: any) => {
			return new Promise(async resolve => {
				const form = new FormData();
				form.append('file', file);
				form.append('type', 'editor');
				resolve(await fetchUploadFile(form));
			});
		}),
	);

	callback(res.map(item => item.data.url));
};

// 加载所有系统文件
const loadAllSystemFiles = async () => {
	try {
		const res = await fetchGetAllFilesList();
		if (res.code === 200) {
			allSystemFiles.value = res.data || [];
			console.log('获取到所有系统文件:', allSystemFiles.value.length, '个');
		}
	} catch (error) {
		console.error('获取系统文件失败:', error);
		ElMessage.error('获取系统文件失败');
	}
};

// 保存文件关联
const saveFileAssociations = async () => {
	if (!editComponentForm.value.nodeId) return;

	fileLoading.value = true;
	try {
		// 确保selectedFileIds是有效的数组
		const fileIds = selectedFileIds.value.filter(Boolean);
		console.log('准备保存的文件IDs:', fileIds);

		// 更新组件关联的文件（全量保存）
		const res = await updateComponentFiles(editComponentForm.value.nodeId, fileIds);

		if (res.code === 200) {
			ElMessage.success('文件关联保存成功');
			// 重新加载组件文件以获取最新的关联信息
			await loadComponentFiles(editComponentForm.value.nodeId);
			// 关闭弹窗
			editDialogVisible.value = false;
			// 刷新案例详情数据
			await fetchCaseDetail(route.params.id as string);
		} else {
			ElMessage.error(res.message || '文件关联保存失败');
		}
	} catch (error) {
		console.error('保存文件关联失败:', error);
		ElMessage.error('保存文件关联失败');
	} finally {
		fileLoading.value = false;
	}
};

// 更新组件关联的知识点
const saveComponentKnowledge = async () => {
	if (!editComponentForm.value.nodeId) return;

	try {
		// 获取子组件中选择的知识点ID列表
		const selectedIds = knowledgeAssignRef.value?.selectedKnowledgeIds || [];
		const res = await updateComponentKnowledge(editComponentForm.value.nodeId, selectedIds);

		if (res.code === 200) {
			ElMessage.success('知识点关联更新成功');
			// 重新加载组件关联的知识点
			await loadComponentKnowledge(editComponentForm.value.nodeId);
			// 关闭弹窗
			editDialogVisible.value = false;
			// 刷新案例详情数据
			await fetchCaseDetail(route.params.id as string);
		} else {
			ElMessage.error(res.message || '知识点关联更新失败');
		}
	} catch (error) {
		console.error('更新组件知识点失败:', error);
		ElMessage.error('更新组件知识点失败');
	}
};

// 下载系统文件
const downloadSystemFile = async fileId => {
	try {
		const blob = await downloadFilesByFileId({ id: fileId });
		const url = window.URL.createObjectURL(blob);
		const a = document.createElement('a');
		a.style.display = 'none';
		a.href = url;
		// 使用响应中的文件名，如果没有则使用默认文件名
		const filename = blob.name || '下载文件';
		a.download = filename;
		document.body.appendChild(a);
		a.click();
		window.URL.revokeObjectURL(url);
		document.body.removeChild(a);
	} catch (error) {
		console.error('下载文件失败:', error);
		ElMessage.error('下载文件失败');
	}
};

// 打开文件管理器
const openFileManager = () => {
	if (!activeComponent.value) {
		ElMessage.warning('请先选择一个组件');
		return;
	}

	// 查找当前活动组件
	const component = caseDetail.value?.components.find(c => c.nodeId === activeComponent.value);
	if (component) {
		// 打开编辑对话框并切换到文件管理标签页
		openEditDialog(component);
		// 设置活动标签为文件管理
		setTimeout(() => {
			activeTab.value = 'files';
		}, 100);
	}
};

// 判断案例是否可以编辑
const canEditCase = (item: any): boolean => {
	// 检查是否有全局案例编辑权限或全局管理权限
	if (hasPerms('case::all')) {
		return true;
	}

	// 获取当前用户名
	const currentUsername = userStore.username;

	// 检查是否是自己创建的案例
	const isCreatedByCurrentUser = item?.createdByUsername === currentUsername;

	// 检查状态是否为草稿(0)或审核未通过(3)
	const isEditableStatus = item?.status === 0 || item?.status === 3;

	return isCreatedByCurrentUser && isEditableStatus;
};

onMounted(() => {
	const id = route.params.id as string;
	if (id) {
		fetchCaseDetail(id);
	} else {
		ElMessage.error('案例ID不存在');
		goBack();
	}
});
</script>

<template>
	<div class="case-detail-view">
		<div class="detail-header bg-bg_color p-4">
			<div class="flex justify-between items-center mb-3">
				<h2 class="text-xl font-bold flex items-center">
					<el-icon class="mr-2 text-primary"><Document /></el-icon>案例详情
				</h2>
				<div>
					<el-button @click="goBack">
						<el-icon><ArrowLeft /></el-icon>
						返回列表
					</el-button>
				</div>
			</div>

			<el-card v-loading="loading" class="box-card case-info-card" shadow="hover">
				<el-row :gutter="24" v-if="caseDetail?.caseInfo">
					<el-col :span="6">
						<div class="case-cover">
							<img v-if="caseDetail.caseInfo.cover" :src="caseDetail.caseInfo.cover" class="w-full h-[180px] object-cover rounded-lg border border-gray-200" />
							<div v-else class="w-full h-[180px] bg-gray-100 flex items-center justify-center rounded-lg border border-gray-200">
								<span class="text-gray-400">暂无封面</span>
							</div>
						</div>
					</el-col>
					<el-col :span="18">
						<div class="case-info">
							<div class="flex justify-between items-start mb-2">
								<h3 class="text-xl font-medium">{{ caseDetail.caseInfo.name }}</h3>
								<el-tag :type="getCaseStatus(caseDetail?.caseInfo?.status)" effect="light" class="status-tag">
									{{ ['草稿', '审核中', '已发布', '审核未通过', '已下架'][caseDetail?.caseInfo?.status || 0] }}
								</el-tag>
							</div>

							<div class="flex gap-2 mb-3">
								<el-tag :type="getCaseDifficulty(caseDetail.caseInfo.difficulty)" size="small" class="difficulty-tag">难度: {{ ['简单', '中等', '困难'][caseDetail.caseInfo.difficulty - 1] }}</el-tag>
								<el-tag type="info" size="small" class="type-tag">类型: {{ caseDetail.caseInfo.type }}</el-tag>
							</div>

							<p class="text-gray-700 whitespace-pre-wrap text-sm mb-3 case-description">{{ caseDetail.caseInfo.description }}</p>

							<div class="meta-info text-xs text-gray-500 flex flex-wrap gap-x-6 gap-y-2 bg-gray-50 p-3 rounded-md">
								<span class="flex items-center">
									<el-icon class="mr-1"><Calendar /></el-icon>
									创建: {{ formatDate(caseDetail.caseInfo.createTime) }}
								</span>
								<span class="flex items-center">
									<el-icon class="mr-1"><Calendar /></el-icon>
									更新: {{ formatDate(caseDetail.caseInfo.updateTime) }}
								</span>
								<span class="flex items-center">
									<el-icon class="mr-1"><User /></el-icon>
									创建者: {{ caseDetail.caseInfo.createdByUsername }}
								</span>
							</div>
						</div>
					</el-col>
				</el-row>
			</el-card>
		</div>

		<div class="component-section bg-bg_color p-4" v-if="caseDetail">
			<el-row :gutter="24" v-if="caseDetail.components && caseDetail.components.length > 0">
				<!-- 左侧组件列表 -->
				<el-col :span="6">
					<el-card class="component-list-card" shadow="hover">
						<template #header>
							<div class="flex justify-between items-center">
								<div class="text-base font-medium flex items-center">
									<el-icon class="mr-2"><Folder /></el-icon>案例组件
								</div>
								<el-button v-if="canEditCase(caseDetail?.caseInfo)" type="primary" size="small" @click="openCreateDialog">
									<el-icon><Plus /></el-icon>
									添加组件
								</el-button>
							</div>
						</template>
						<div class="component-list">
							<div
								v-for="component in caseDetail.components"
								:key="component.nodeId"
								class="component-item"
								:class="{ 'is-active': component.nodeId === activeComponent }"
								@click="activeComponent = component.nodeId"
							>
								<el-icon class="component-icon"><Folder /></el-icon>
								<span class="component-name">{{ component.name }}</span>
								<el-icon v-if="component.nodeId === activeComponent" class="active-icon"><ArrowRight /></el-icon>
							</div>
						</div>
					</el-card>
				</el-col>

				<!-- 右侧组件详情 -->
				<el-col :span="18" v-if="activeComponent">
					<el-card class="component-detail-card" shadow="hover">
						<template #header>
							<div class="flex justify-between items-center">
								<h3 class="text-base font-medium flex items-center">
									<el-icon class="mr-2"><Document /></el-icon>
									{{ caseDetail.components.find(c => c.nodeId === activeComponent)?.name }}
								</h3>
								<div>
									<el-button v-if="canEditCase(caseDetail?.caseInfo)" type="primary" size="small" @click="openEditDialog(caseDetail.components.find(c => c.nodeId === activeComponent))" class="edit-button">
										<el-icon><Edit /></el-icon>
										编辑组件
									</el-button>
								</div>
							</div>
						</template>

						<div v-if="caseDetail.components.find(c => c.nodeId === activeComponent)" class="mb-4 component-content">
							<!-- 相关知识点标签组 -->
							<div v-if="getCurrentComponentKnowledge(activeComponent).length > 0" class="knowledge-tags mb-5 bg-blue-50 p-4 rounded-lg">
								<div class="flex items-center mb-3">
									<el-icon class="mr-2 text-primary"><Collection /></el-icon>
									<span class="text-base font-medium">相关知识点</span>
								</div>
								<div class="flex flex-wrap gap-2">
									<el-popover v-for="knowledge in getCurrentComponentKnowledge(activeComponent)" :key="knowledge.nodeId" placement="top" :width="320" trigger="hover" popper-class="knowledge-popover">
										<template #default>
											<div class="knowledge-detail">
												<h4 class="font-medium mb-2 text-primary">{{ knowledge.name }}</h4>
												<p class="text-sm text-gray-600 mb-2">{{ knowledge.description }}</p>
												<div v-if="knowledge.summary" class="text-sm mb-2 bg-gray-50 p-2 rounded"><strong>摘要:</strong> {{ knowledge.summary }}</div>
												<div class="flex flex-wrap gap-1 mt-2">
													<el-tag v-for="tag in knowledge.tags" :key="tag" size="small" effect="plain">{{ tag }}</el-tag>
												</div>
											</div>
										</template>
										<template #reference>
											<el-tag :type="getKnowledgeTagType(knowledge.level)" class="knowledge-tag">
												{{ knowledge.name }}
											</el-tag>
										</template>
									</el-popover>
								</div>
							</div>

							<!-- 组件描述 -->
							<div class="component-description mb-5">
								<h4 class="text-base font-medium mb-2 flex items-center">
									<el-icon class="mr-2 text-primary"><Document /></el-icon>组件描述
								</h4>
								<div class="bg-gray-50 p-4 rounded-lg mb-4 border-l-4 border-primary">
									<p class="whitespace-pre-wrap">{{ caseDetail.components.find(c => c.nodeId === activeComponent)?.description }}</p>
								</div>
							</div>

							<!-- 组件内容 -->
							<div v-if="caseDetail.components.find(c => c.nodeId === activeComponent)?.content" class="mb-5">
								<h4 class="text-base font-medium mb-2 flex items-center">
									<el-icon class="mr-2 text-primary"><Document /></el-icon>组件内容
								</h4>
								<div class="bg-gray-50 p-4 rounded-lg code-content shadow-sm">
									<MdPreview :model-value="caseDetail.components.find(c => c.nodeId === activeComponent)?.content || ''" />
								</div>
							</div>

							<!-- 组件相关文件 -->
							<div class="mb-4" v-if="getCurrentComponentFiles(activeComponent).length > 0">
								<div class="flex justify-between items-center mb-3">
									<h4 class="text-base font-medium flex items-center">
										<el-icon class="mr-2 text-primary"><Document /></el-icon>相关文件
									</h4>
									<el-button v-if="canEditCase(caseDetail?.caseInfo)" type="primary" size="small" @click="openFileManager" class="edit-button">
										<el-icon><Edit /></el-icon>
										管理文件
									</el-button>
								</div>
								<div class="file-list">
									<!-- 文件列表 -->
									<el-table :data="getCurrentComponentFiles(activeComponent)" style="width: 100%" class="file-table" border>
										<el-table-column type="expand">
											<template #default="props">
												<div class="file-preview-container">
													<div class="file-preview-header flex justify-between items-center mb-3">
														<div class="font-medium flex items-center">
															<el-icon class="mr-2 text-primary"><Document /></el-icon>
															{{ props.row.filename }} 预览
														</div>
														<el-button type="primary" link size="small" @click="previewFile(props.row.url)">
															<el-icon><View /></el-icon>
															在新窗口预览
														</el-button>
													</div>
													<FilePreview :url="props.row.url" previewServer="http://127.0.0.1:8012" />
												</div>
											</template>
										</el-table-column>
										<el-table-column label="文件名" prop="filename">
											<template #default="{ row }">
												<div class="flex items-center">
													<el-icon class="mr-2 text-primary"><Document /></el-icon>
													<span>{{ row.filename }}</span>
												</div>
											</template>
										</el-table-column>
										<el-table-column label="文件类型" prop="fileType" width="180">
											<template #default="{ row }">
												<el-tag size="small" effect="plain">{{ formatFileType(row.fileType) }}</el-tag>
											</template>
										</el-table-column>
										<el-table-column label="文件大小" prop="fileSize" width="120">
											<template #default="{ row }">{{ Math.floor(row.fileSize / 1024) }}KB</template>
										</el-table-column>
										<el-table-column label="操作" width="120">
											<template #default="{ row }">
												<el-button type="success" link @click="row.fileId ? downloadSystemFile(row.fileId) : openFile(row.url)">
													<el-icon><Download /></el-icon>
													<span>下载</span>
												</el-button>
											</template>
										</el-table-column>
									</el-table>
								</div>
							</div>

							<!-- 如果没有关联文件时显示添加文件按钮 -->
							<div class="mb-4" v-else>
								<div class="flex justify-between items-center mb-3">
									<h4 class="text-base font-medium flex items-center">
										<el-icon class="mr-2 text-primary"><Document /></el-icon>相关文件
									</h4>
								</div>
								<el-empty description="暂无关联文件">
									<el-button v-if="canEditCase(caseDetail?.caseInfo)" type="primary" @click="openFileManager">添加文件</el-button>
								</el-empty>
							</div>
						</div>
					</el-card>
				</el-col>

				<!-- 没有选中组件时的提示 -->
				<el-col :span="18" v-else>
					<el-empty description="请选择一个组件查看详情" />
				</el-col>
			</el-row>

			<!-- 当没有组件时显示的提示和添加按钮 -->
			<el-row v-else>
				<el-col :span="24">
					<el-card class="empty-component-card" shadow="hover">
						<div class="flex flex-col items-center justify-center py-8">
							<el-empty description="暂无组件" class="mb-6">
								<template #image>
									<el-icon style="font-size: 60px; color: var(--el-color-info-light-3)"><Folder /></el-icon>
								</template>
							</el-empty>
							<p v-if="canEditCase(caseDetail?.caseInfo)" class="text-gray-500 mb-6">该案例尚未添加任何组件，请点击下方按钮添加组件</p>
							<el-button v-if="canEditCase(caseDetail?.caseInfo)" type="primary" @click="openCreateDialog" size="large" icon="Plus"> 添加第一个组件 </el-button>
						</div>
					</el-card>
				</el-col>
			</el-row>
		</div>

		<!-- 编辑组件对话框 -->
		<el-dialog v-model="editDialogVisible" title="编辑组件" width="70%" :close-on-click-modal="false" destroy-on-close>
			<el-tabs v-model="activeTab" class="component-edit-tabs">
				<el-tab-pane label="基本信息" name="basic">
					<div v-loading="editFormLoading">
						<el-form :model="editComponentForm" label-position="top">
							<el-form-item label="组件名称" required>
								<el-input v-model="editComponentForm.name" placeholder="请输入组件名称" />
							</el-form-item>

							<el-form-item label="组件描述" required>
								<el-input v-model="editComponentForm.description" type="textarea" :rows="3" placeholder="请输入组件描述" />
							</el-form-item>

							<el-form-item label="组件内容">
								<div class="markdown-editor-container">
									<MdEditor v-model="editComponentForm.content" :showToolbarName="true" style="height: 400px" @onUploadImg="onUploadImg" />
								</div>
							</el-form-item>
						</el-form>
						<div class="mt-4 flex justify-end">
							<el-button @click="editDialogVisible = false">取消</el-button>
							<el-button type="primary" @click="saveComponentEdit" :loading="editFormLoading">保存</el-button>
						</div>
					</div>
				</el-tab-pane>

				<el-tab-pane label="文件管理" name="files">
					<div v-loading="fileLoading" class="files-tab-content">
						<!-- 当前已关联文件预览 -->
						<div class="mb-4 p-3 bg-blue-50 rounded-lg">
							<h4 class="text-sm font-medium mb-2 flex items-center">
								<el-icon class="mr-1"><Document /></el-icon>
								当前已关联文件 ({{ componentFiles.length }})
							</h4>
							<div class="flex flex-wrap gap-2">
								<el-tag v-for="file in componentFiles" :key="file.fileId" class="mr-1 mb-1" effect="plain" type="success">
									<span class="flex items-center">
										<el-icon class="mr-1"><Document /></el-icon>
										{{ file.filename }}
									</span>
								</el-tag>
								<div v-if="componentFiles.length === 0" class="text-gray-400 text-sm">暂无关联文件</div>
							</div>
						</div>

						<!-- 搜索区域 -->
						<div class="mb-4 flex items-center bg-gray-50 p-3 rounded-lg">
							<el-input v-model="fileSearchKeyword" placeholder="搜索文件名或类型" clearable class="w-[300px]">
								<template #prefix>
									<el-icon><Search /></el-icon>
								</template>
							</el-input>
							<div class="ml-2 text-sm text-gray-500">找到 {{ filteredSystemFiles.length }} 个文件</div>
							<div class="ml-auto text-sm text-gray-500">已选择 {{ selectedFileIds.length }} 个文件</div>
						</div>

						<!-- 系统文件列表 -->
						<el-table ref="fileTableRef" :data="filteredSystemFiles" style="width: 100%" border @selection-change="handleSelectionChange" max-height="500" v-loading="fileLoading">
							<el-table-column type="selection" width="55" />
							<el-table-column label="文件名" prop="filename" min-width="180">
								<template #default="{ row }">
									<div class="flex items-center">
										<el-icon class="mr-2 text-primary"><Document /></el-icon>
										<span>{{ row.filename }}</span>
									</div>
								</template>
							</el-table-column>
							<el-table-column label="文件类型" prop="fileType" width="180">
								<template #default="{ row }">
									<el-tag size="small" effect="plain">{{ formatFileType(row.fileType) }}</el-tag>
								</template>
							</el-table-column>
							<el-table-column label="文件大小" prop="fileSize" width="120">
								<template #default="{ row }">{{ Math.floor(row.fileSize / 1024) }}KB</template>
							</el-table-column>
							<el-table-column label="操作" width="100">
								<template #default="{ row }">
									<el-button type="primary" link @click="downloadSystemFile(row.fileId)">
										<el-icon><Download /></el-icon>
										<span>下载</span>
									</el-button>
								</template>
							</el-table-column>
						</el-table>

						<el-empty v-if="filteredSystemFiles.length === 0" description="暂无系统文件" />

						<div class="mt-4 flex justify-end">
							<el-button @click="editDialogVisible = false">取消</el-button>
							<el-button type="primary" @click="saveFileAssociations" :loading="fileLoading">保存文件关联</el-button>
						</div>
					</div>
				</el-tab-pane>

				<el-tab-pane label="知识点管理" name="knowledge">
					<div v-loading="knowledgeLoading" class="knowledge-tab-content">
						<AssignKnowledgeToComponent ref="knowledgeAssignRef" :component-id="editComponentForm.nodeId" :knowledge-list="componentKnowledge" />

						<div class="current-knowledge-list">
							<h4 class="text-base font-medium mb-2">当前关联的知识点</h4>
							<div class="flex flex-wrap gap-2 mt-2">
								<el-tag v-for="knowledge in componentKnowledge" :key="knowledge.nodeId" :type="getKnowledgeTagType(knowledge.level)" class="knowledge-tag">
									{{ knowledge.name }}
								</el-tag>
							</div>

							<el-empty v-if="componentKnowledge.length === 0" description="暂无关联知识点" />
						</div>

						<div class="mt-4 flex justify-end">
							<el-button @click="editDialogVisible = false">取消</el-button>
							<el-button type="primary" @click="saveComponentKnowledge" :loading="knowledgeLoading">保存知识点关联</el-button>
						</div>
					</div>
				</el-tab-pane>
			</el-tabs>
		</el-dialog>

		<!-- 创建组件对话框 -->
		<el-dialog v-model="createDialogVisible" title="创建组件" width="70%" :close-on-click-modal="false" destroy-on-close>
			<el-tabs v-model="activeTab" class="component-edit-tabs">
				<el-tab-pane label="基本信息" name="basic">
					<div v-loading="createFormLoading">
						<el-form :model="createComponentForm" label-position="top">
							<el-form-item label="组件名称" required>
								<el-input v-model="createComponentForm.name" placeholder="请输入组件名称" />
							</el-form-item>

							<el-form-item label="组件描述" required>
								<el-input v-model="createComponentForm.description" type="textarea" :rows="3" placeholder="请输入组件描述" />
							</el-form-item>

							<el-form-item label="组件内容">
								<div class="markdown-editor-container">
									<MdEditor v-model="createComponentForm.content" :showToolbarName="true" style="height: 400px" @onUploadImg="onUploadImg" />
								</div>
							</el-form-item>
						</el-form>
					</div>
				</el-tab-pane>
			</el-tabs>

			<template #footer>
				<span class="dialog-footer">
					<el-button @click="createDialogVisible = false">取消</el-button>
					<el-button type="primary" @click="handleCreateComponent" :loading="createFormLoading">创建</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<style lang="scss" scoped>
.case-detail-view {
	min-height: calc(100vh - 80px);
	background-color: #f5f7fa;
	display: flex;
	flex-direction: column;
}

.detail-header {
	margin-bottom: 0;
}

.text-primary {
	color: var(--el-color-primary);
}

.border-primary {
	border-color: var(--el-color-primary);
}

.case-info-card {
	// 移除 hover 动画效果
}

.component-list-card,
.component-detail-card {
	height: 100%;
	border-radius: 12px;
	overflow: hidden;

	// 移除 hover 动画效果

	:deep(.el-card__header) {
		padding: 12px 16px;
		font-weight: 500;
		background-color: #f9f9f9;
		border-bottom: 1px solid #eaeaea;
	}

	:deep(.el-card__body) {
		padding: 16px;
	}
}

.component-detail-card {
	min-height: 600px;
}

.component-list {
	padding: 4px;
}

.component-item {
	display: flex;
	align-items: center;
	padding: 12px;
	margin-bottom: 6px;
	border-radius: 8px;
	cursor: pointer;
	transition: all 0.2s ease;
	position: relative;
	border: 1px solid transparent;

	.component-icon {
		margin-right: 10px;
		font-size: 18px;
	}

	.component-name {
		font-size: 14px;
		line-height: 1.5;
		flex: 1;
	}

	.active-icon {
		position: absolute;
		right: 10px;
		font-size: 16px;
	}

	&:hover {
		background-color: var(--el-color-primary-light-9);
		border-color: var(--el-color-primary-light-5);
	}

	&.is-active {
		background-color: var(--el-color-primary);
		color: white;
		font-weight: 500;
		box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);
	}
}

.case-description {
	max-height: 3.6em;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	line-height: 1.8;
}

.code-content {
	max-height: 600px;
	overflow-y: auto;
	border-radius: 8px;
	border: 1px solid #ebeef5;
}

.knowledge-tag {
	cursor: pointer;
	transition: all 0.3s;
	font-weight: 500;
	border-radius: 4px;
	padding: 6px 10px;

	&:hover {
		transform: translateY(-2px);
		box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
	}
}

.status-tag,
.difficulty-tag,
.type-tag {
	font-weight: 500;
	padding: 4px 8px;
	border-radius: 4px;
}

:deep(.md-editor-preview-wrapper) {
	background-color: transparent;
	padding: 0;
}

:deep(.knowledge-popover) {
	max-width: 320px;
	border-radius: 8px;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);

	.el-popover__title {
		font-weight: bold;
		margin-bottom: 8px;
	}
}

.knowledge-detail {
	h4 {
		margin-top: 0;
		font-size: 16px;
	}
}

:deep(.el-card) {
	border-radius: 12px;
	overflow: hidden;
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}

.box-card {
	:deep(.el-card__header) {
		display: none;
	}
}

.meta-info {
	color: var(--el-text-color-secondary);
}

.case-cover {
	img,
	div {
		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
		transition: all 0.3s ease;
		&:hover {
			transform: translateY(-2px);
			box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
		}
	}
}

.file-preview-container {
	padding: 20px;
	margin: 0;
	background-color: #f8f9fa;
	border-radius: 8px;
	overflow: hidden;
	width: 100%;
	box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.05);
}

.file-preview-header {
	padding-bottom: 12px;
	margin-bottom: 12px;
	border-bottom: 1px solid #eaeaea;
}

.file-table {
	border-radius: 8px;
	overflow: hidden;
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}

.component-content {
	h4 {
		margin-top: 0;
	}
}

.markdown-editor-container {
	border: 1px solid #e0e0e0;
	border-radius: 4px;
}

/* 覆盖Element Plus表格样式 */
:deep(.el-table__expand-icon) {
	color: var(--el-color-primary);
	font-size: 16px;
}

:deep(.el-table__expanded-cell) {
	padding: 20px;
}

:deep(.el-table) {
	--el-table-border-color: #e0e0e0;
	--el-table-header-bg-color: #f5f7fa;
	.el-table__header th {
		background-color: #f5f7fa;
		font-weight: 500;
	}
}

.component-edit-tabs {
	height: 100%;
}

.files-tab-content,
.knowledge-tab-content {
	min-height: 400px;
}

.current-knowledge-list {
	margin-top: 20px;
	padding-top: 20px;
	border-top: 1px dashed #eaeaea;
}

// 添加文件管理相关样式
.el-tag {
	transition: all 0.3s;
	&:hover {
		transform: translateY(-2px);
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
	}
}

.edit-button {
	&:hover {
		transform: translateY(-1px);
	}
}

.file-table {
	transition: all 0.3s;

	.el-table__row {
		cursor: pointer;
		&:hover {
			background-color: var(--el-color-primary-light-9);
		}
	}
}
</style>
